#!/usr/bin/perl -w
use strict;
use IO::File;
use Bio::SeqIO;
#Copyright 2011. Jason Weirather.
#This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License v3 or any later version.
#This file is useful when you change your mind about how you want
#to color code a 'dot' file but you want to be sure to be using
#the exact same dot file without re-running the BLAST.  This will
#Take as an input a dot file that contains the mapping informaton
#which you would like to recolor and a fasta file that contains the 
#new coloring scheme.  you also need to tell it where to write out
#the new legend file to.  This can be used later with printLegend to 
#print out the new legend file

#the script will read in both files, then use the new coloring scheme 
#to change the colors in the dot file.  Then the programs you use to
#display these should have a more comparable output.  
if(scalar(@ARGV) < 3) { die "use ./recolorDot dotfilename.dot fastawithnewcolorscheme.fasta anythingyouwant.legend\n"; }
my ($dotfilename,$fastafilename,$legendfilename) = @ARGV;

open (DF, "$dotfilename") or die "couldn't open dot file $dotfilename\n";
open (FF, "$fastafilename") or die "couldn't open fasta file $fastafilename\n";
chomp(my @dotlines = <DF>);
close DF;
chomp(my @fastalines = <FF>);
close FF;
#lets get the new name/type scheme from that fasta file
#the format is the typical visblast format
my %nametoNewtype;
my %newtypes;
foreach my $fastaline (@fastalines) {
  if($fastaline=~/^>(.*)/) { #found a line;
    my $fieldline = $1;
    my @fields = split(/\s+/,$fieldline);
    my $name = shift @fields;
    my $newtype = shift @fields;
    $nametoNewtype{$name} = $newtype;
    $newtypes{$newtype} = 1;
  }
}
#make the equivilent of the temporary whatever.result.legend that usually
#holds all the legend information
my %colorMap;
open (LF,">$legendfilename") or die "could not open to write to $legendfilename\n";
foreach my $newtype (sort {$a cmp $b} (keys(%newtypes))) {
  $colorMap{$newtype} = sprintf "#%x%x%x%x%x%x", map { rand(16) } 1 .. 6;
  print LF "$newtype\t$colorMap{$newtype}\n";
}
close LF;
#now go through our nametoNewtype and make nametoNewcolor
my %nametoNewcolor;
foreach my $name (keys(%nametoNewtype)) {
  if(exists($colorMap{$nametoNewtype{$name}})) { 
    $nametoNewcolor{$name} = $colorMap{$nametoNewtype{$name}}; 
  }
} # thats it son.  Now we have a hash to convert the names we encounter in the dot file to the new color when availible.
#now lets pull out some names from that graph file.  make sure we have colors
#for all of them so if we don't we can add to our legend.  
foreach my $dotline (@dotlines) { 
  if($dotline=~/^\"(\S+)\"\s+/) {  # we have a name in the dot file.
    my $name = $1;
    if(!exists($nametoNewcolor{$name})) { die "color info for $name is missing\n"; } 
    if($dotline=~/^(\"\S+\")(.+fillcolor=\")(\S+)(\".*)/) {
      my $firstnamepart = $1;
      my $secondsave = $2;
      my $thridreplace = $3;
      my $fourthsave = $4;
      #make the swap here
      print "\"$name\"$secondsave" . $nametoNewcolor{$name} . "$fourthsave\n";
    } else { die " could not parse dot line $dotline\n"; } 
  } else {
    print "$dotline\n";
  }
}
